import sys
import os

'''
面向对象：
面向对象是一种编程范式，它将数据和操作数据的方法封装在一起，形成一个对象。

'''

# 获取当前文件的绝对路径
current_file_path = os.path.abspath(__file__)

# 获取当前文件所在目录的绝对路径
current_dir = os.path.dirname(current_file_path)

# 获取当前目录的父目录
parent_dir = os.path.dirname(current_dir)

print(f"当前文件的绝对路径: {current_file_path}")
print(f"当前目录的绝对路径: {current_dir}")
print(f"当前目录的父目录: {parent_dir}")

# 添加外部包的路径
external_package_path = os.path.join(parent_dir, 'package1')
print(f"外部包的路径: {external_package_path}")
# sys.path.append(external_package_path)
sys.path.append(parent_dir)

# 现在可以导入外部包中的类
# from external_module import ExternalClass  

# 使用导入的类
# ec = ExternalClass()
# ec.some_method()

from package1 import TheFirstDemo as fd
from package1 import CLanguage as cl
from package1 import SecondDemo as sd
from package1 import PropertyDemo as pd

# 如果将package1文件夹放在当前目录下，则不需要添加路径
# import TheFirstDemo as fd
# import CLanguage as cl
# import SecondDemo as sd
# import PropertyDemo as pd




class Car(object):
    # 类变量
    name = '汽车'
    add = '北京'

    # 构造函数，直接在构造方法里面定义成员变量
    def __init__(self, name, add):
        # 实例变量
        self.name = name
        self.add = add

    # 实例方法，第一个参数必须是self，self代表实例对象本身。
    # 实例方法默认是公有的
    def say(self, name):
        print('我是', name)

    # 类方法，第一个参数必须是cls，cls代表类本身。
    @classmethod
    def print(cls):
        print('我是类方法')
        print(f"{cls.name},{cls.add}")

    # 静态方法
    @staticmethod
    def show():
        print('我是静态方法')

    # 析构函数
    def __del__(self):
        print('我是析构函数')

    # 私有方法
    def __private_method(self):
        print('我是私有方法')

    # 私有属性
    __private_attribute = '我是私有属性'
    # 私有属性的访问方法
    def get_private_attribute(self):
        return self.__private_attribute

    # 私有属性的修改方法
    def set_private_attribute(self, value):
        self.__private_attribute = value

    # 私有属性的删除方法
    def del_private_attribute(self):
        del self.__private_attribute



class Employee:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age
    def show(self):
        print(f"姓名：{self.__name}，年龄：{self.__age}")
    def __del__(self):
        print("对象已被删除")

    @property
    def name(self):
        return self.__name
    @property
    def age(self):
        return self.__age
    @name.setter
    def name(self, name):
        self.__name = name
    @age.setter
    def age(self, age):
        self.__age = age

    # 这个方法，调用print()时，会自动调用。
    def __str__(self):
        return f"姓名：{self.__name}，年龄：{self.__age}"
    def __repr__(self):
        return f"姓名：{self.__name}，年龄：{self.__age}"
























# 主函数
if __name__ == "__main__":

    # 自定义了构造函数，默认的构造函数失效了
    # ad = fd.TheFirstDemo()

    ad = fd.TheFirstDemo('www.sina.com')

    ad.say("aaa")

    ad.print()

    lan = cl.CLanguage('百度', 'http://www.baidu.com')

    # 通过类名直接访问类变量
    cl.CLanguage.name = '新浪'
    cl.CLanguage.add = 'http://www.sina.com'

    print(cl.CLanguage.name, cl.CLanguage.add)

    sdemo = sd.SecondDemo('网易', 'www.163.com')
    sdemo.show()
    name = sdemo.name
    print(name)

    p = pd.Person("yejing", 36)
    p.setName('hello')
    p.show()


    car = Car('宝马', '北京')
    car.say('宝马')
    car.print()
    car.show()
    try:
        # 访问私有属性
        car.set_private_attribute('我是私有属性22222')
        pa = car.get_private_attribute()
        print(pa)
    except AttributeError as e:
        print('访问私有属性失败')
    # 程序结束，会自动调用析构函数。


    em = Employee('yejing', 36)
    em.show()
    print(em)
    print(em.name)